/*
 * jlb
 */
package com.jlb.active.service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.baidu.fsg.uid.UidGenerator;
import com.jlb.active.dao.ActivePoolDAO;
import com.jlb.active.dao.ActiveRecordDAO;
import com.jlb.active.entity.ActivePool;
import com.jlb.active.entity.ActivePoolState;
import com.jlb.active.entity.ActiveRecord;
import com.jlb.core.base.BaseDAO;
import com.jlb.core.base.BaseSVImpl;
import com.jlb.core.entity.Page;
import com.jlb.core.enums.YNEnum;
import com.jlb.core.exceptions.*;
import com.jlb.core.tools.security.Md5;
import com.jlb.user.dao.UserActiveDAO;
import com.jlb.user.entity.User;
import com.jlb.user.entity.UserActive;
import com.jlb.user.entity.UserLeaderEnum;
import com.jlb.user.entity.UserState;
import com.jlb.user.service.UserSV;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.apache.ibatis.session.RowBounds;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service("activePoolSV")
@Slf4j
public class ActivePoolSVImpl extends BaseSVImpl<ActivePool, Long> implements ActivePoolSV {

    @Resource
    private ActivePoolDAO activePoolDAO;

    @Resource
    private UserSV userSV;

    @Resource
    private UserActiveDAO userActiveDAO;

    @Resource
    private ActiveRecordDAO activeRecordDAO;

    @Resource
    private UidGenerator uidGenerator;

    @Override
    protected BaseDAO getBaseDAO() {
        return activePoolDAO;
    }

    /**
     * 保存account对象
     *
     * @param entity 实体
     * @throws BaseException
     */
    @Override
    public void save(ActivePool entity) throws BaseException {
        entity.setCreateTime(new Date());
        super.save(entity);
    }

    /**
     * 加载一个对象ActivePool
     *
     * @param id
     * @return ActivePool
     */
    @Override
    public ActivePool load(java.lang.Long id) {
        if (id == null) {
            throw new ActivePoolException(BaseException.BaseExceptionEnum.Ilegal_Param);
        }

        Map<String, Object> param = new HashMap<>();
        param.put("id", id);
        return activePoolDAO.load(param);
    }

    /**
     * 加载一个对象ActivePool 通过id
     *
     * @param id
     * @return ActivePool
     */
    @Override
    public ActivePool loadById(java.lang.Long id) {
        if (id == null) {
            throw new ActivePoolException(BaseException.BaseExceptionEnum.Ilegal_Param);
        }
        return activePoolDAO.loadById(id);
    }


    /**
     * 根据主键id,oldStates 共同更新 ActivePool 的状态到newState状态
     *
     * @param id
     * @param newState  新状态
     * @param oldStates 旧状态集合
     */
    @Override
    public void updateStateById(java.lang.Long id, ActivePoolState newState, ActivePoolState... oldStates) {
        if (id == null) {
            throw new ActivePoolException(BaseException.BaseExceptionEnum.Ilegal_Param);
        }
        if (newState == null) {
            throw new ActivePoolException(BaseException.BaseExceptionEnum.Ilegal_Param);
        }
        if (oldStates == null) {
            throw new ActivePoolException(BaseException.BaseExceptionEnum.Ilegal_Param);
        }
        activePoolDAO.updateStateById(id, new Date(), newState, oldStates);
    }

    /**
     * 根据主键id 更新 ActivePool 的状态到另一个状态
     *
     * @param id
     * @param state 状态
     */
    @Override
    public void updateById(java.lang.Long id, ActivePoolState state) {
        if (id == null) {
            throw new ActivePoolException(BaseException.BaseExceptionEnum.Ilegal_Param);
        }
        activePoolDAO.updateById(id, state, new Date());
    }


    /**
     * 删除对象ActivePool
     *
     * @param id
     * @return ActivePool
     */
    @Override
    public void delete(java.lang.Long id) {
        if (id == null) {
            throw new ActivePoolException(BaseException.BaseExceptionEnum.Ilegal_Param);
        }
        Map<String, Object> param = new HashMap<>();
        param.put("id", id);
        activePoolDAO.delete(param);
    }


    /**
     * 查询ActivePool分页
     *
     * @param activePool 对象
     * @param offset     查询开始行
     * @param limit      查询行数
     * @return List<ActivePool>
     */
    @Override
    public List<ActivePool> list(ActivePool activePool, int offset, int limit) {
        if (offset < 0) {
            offset = 0;
        }

        if (limit < 0) {
            limit = Page.limit;
        }

        Map<String, Object> map = null;
        if (activePool != null) {
            map = JSON.parseObject(JSON.toJSONString(activePool, SerializerFeature.WriteDateUseDateFormat));
        } else {
            map = new HashMap<>();
        }
        return activePoolDAO.list(map, new RowBounds(offset, limit));
    }

    @Override
    public int count(ActivePool activePool) {
        Map<String, Object> map = null;
        if (activePool != null) {
            map = JSON.parseObject(JSON.toJSONString(activePool, SerializerFeature.WriteDateUseDateFormat));
        } else {
            map = new HashMap<>();
        }
        return activePoolDAO.count(map);
    }

    /**
     * 查询ActivePool分页
     *
     * @param id
     * @param offset 查询开始行
     * @param limit  查询行数
     * @return List<ActivePool>
     */
    @Override
    public List<ActivePool> list(java.lang.Long id, int offset, int limit) {
        if (offset < 0) {
            offset = 0;
        }

        if (limit < 0) {
            limit = Page.limit;
        }
        Map<String, Object> param = new HashMap<>();
        param.put("id", id);
        return activePoolDAO.list(param, new RowBounds(offset, limit));
    }

    @Override
    public int count(java.lang.Long id) {
        Map<String, Object> param = new HashMap<>();
        param.put("id", id);
        return activePoolDAO.count(param);
    }

    /**
     * 生成激活码
     *
     * @param num   数量
     * @param price 价格
     */
    @Override
    public void save(Integer num, Double price) {
        if (num == null || num <= 0) {
            throw new ActivePoolException(BaseException.BaseExceptionEnum.Ilegal_Param);
        }
        if (price == null || price.doubleValue() < 0) {
            price = new Double(0);
        }
        ActivePool activePool;
        for (int i = 0; i < num; i++) {
            activePool = new ActivePool();
            activePool.setCode(uidGenerator.getUID() + "");
            activePool.setState(ActivePoolState.Normal.name());
            activePool.setPrice(String.valueOf(price));
            activePool.setCreateTime(new Date());
            super.save(activePool);
        }
    }

    /**
     * 批量转给领导人
     */
    @Override
    public void batchTransfer(String account, String active) {
//        if (StringUtils.isEmpty(account)) {
//            throw new ActivePoolException(BaseException.BaseExceptionEnum.Ilegal_Param);
//        }
//        if (StringUtils.isEmpty(actives)) {
//            throw new ActivePoolException(BaseException.BaseExceptionEnum.Ilegal_Param);
//        }
//        //1.查询用户信息是否存在
//        User user = userSV.loadByAccount(account);
//        if (user == null) {
//            throw new ActivePoolException(BaseException.BaseExceptionEnum.User_Error);
//        }
//        //2.用户是否是领导人
//        if (YNEnum.N.equals(YNEnum.getYN(user.getIsLeader()))) {
//            throw new ActivePoolException(BaseException.BaseExceptionEnum.Not_Is_Leader);
//        }
//        //3.开始保存数据
//        String[] arrays = actives.split(",");
//        if (arrays.length > 0) {
//            UserActive userActive;
//            Map<String, Object> params;
//            ActivePool activePool;
//            for (int i = 0; i < arrays.length; i++) {
//                activePool = activePoolDAO.loadByCode(arrays[i]);
//                if (activePool != null && ActivePoolState.Normal.equals(ActivePoolState.getEnum(activePool.getState()))) {
//                    userActive = new UserActive();
//                    userActive.setUserCode(user.getCode());
//                    userActive.setActiveCode(arrays[i]);
//                    userActiveDAO.insert(userActive);
//                    //修改激活码池状态
//                    params = new HashedMap();
//                    params.put("code", arrays[i]);
//                    params.put("state", ActivePoolState.Received.name());
//                    activePoolDAO.update(params);
//                }
//            }
//        }
    }

    /**
     * 用户互转激活码
     *
     * @param sendUser      发送者编码
     * @param acceptAccount 接受者账户
     * @param num           要转的激活码数量
     * @param pinPassword   支付密码
     * @return boolean
     */
    @Override
    public void userTransfer(User sendUser, String acceptAccount, Integer num, String pinPassword) {
        //1.发送者状态
        //用户状态是否正常
        if (UserState.Active != UserState.getEnum(sendUser.getState())) {
            throw new ActivePoolException(BaseException.BaseExceptionEnum.User_Not_Active);
        }
        //交易密码是否正确
        if (!Md5.md5(pinPassword).equals(sendUser.getPinPassword())) {
            throw new UserOreException(BaseException.BaseExceptionEnum.Pin_Password_Is_Error);
        }
        //2.接收者状态
        User acceptUser = userSV.loadByAccount(acceptAccount);
        if (acceptUser == null) {
            throw new ActivePoolException(BaseException.BaseExceptionEnum.User_Error);
        }
        if (UserState.Active != UserState.getEnum(acceptUser.getState())) {
            throw new ActivePoolException(BaseException.BaseExceptionEnum.User_Not_Active);
        }
        //判断是否给自己转账
        if (sendUser.getCode().equals(acceptUser.getCode())) {
            throw new UserJlbException(BaseException.BaseExceptionEnum.Not_Allow_Transfer_Yourself);
        }

        //禁止领导人互转

        if (UserLeaderEnum.getEnum(sendUser.getLeader()) == UserLeaderEnum.Leader && UserLeaderEnum.getEnum(acceptUser.getLeader()) == UserLeaderEnum.Leader) {
            throw new UserJlbException(BaseException.BaseExceptionEnum.Not_Allow_Transfer);
        }

        //3.用户是否具有足够的激活码
        Map<String, Object> param = new HashMap<>();
        param.put("userCode", sendUser.getCode());
        UserActive sendUserActive = userActiveDAO.load(param);
        if (sendUserActive == null) {
            userActiveDAO.insert(new UserActive(sendUser.getCode(), 0));
            throw new UserActiveException(BaseException.BaseExceptionEnum.Active_Not_Enough_Error);
        }
        if (sendUserActive.getActive() < num) {
            throw new UserActiveException(BaseException.BaseExceptionEnum.Active_Not_Enough_Error);
        }

        param.put("userCode", acceptUser.getCode());
        UserActive acceptUserActive = userActiveDAO.load(param);
        if (acceptUserActive == null) {
            acceptUserActive = new UserActive(acceptUser.getCode(), 0);
            userActiveDAO.insert(acceptUserActive);
        }

        //5.转送激活码
        //转出
        sendUserActive.setActive(sendUserActive.getActive() - num);
        userActiveDAO.update(sendUserActive);
        activeRecordDAO.insert(new ActiveRecord(String.valueOf(num * (-1)), sendUser.getCode(), "[" + sendUser.getAccount() + "]向账户[" + acceptAccount + "]转激活币[" + num + "]个"));

        //接受
        acceptUserActive.setActive(acceptUserActive.getActive() + num);
        userActiveDAO.update(acceptUserActive);
        activeRecordDAO.insert(new ActiveRecord(String.valueOf(num), sendUser.getCode(), "[" + acceptAccount + "]接受来自账户[" + sendUser.getAccount() + "]转的激活币[" + num + "]个"));

    }

}
